<?php

namespace AppBundle\Controller;

use AdminBundle\Entity\HuobiCalcKline5min;
use AdminBundle\Entity\HuobiMarketKline5min;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Request;
use AdminBundle\Entity\HuobiAmazingLog;

use AppBundle\Task\AlertModelConfig;

class HuobiKLinePre5minController extends HuobiKlineBaseController
{
    const CACHE_KLINE_KEY = 'list:kline_amazing';

    /**
     * 接收WEBSOCKET同步过来的当前K线图（5分钟）数据,即未完成的5分钟数据,例1,2,3,4,6,7,8,9,11,12,13,14,...
     * @Route("/kline_pre5min", name="huobi_market_kline_pre5min")
     */
    public function indexAction(Request $request)
    {
        $content = $request->getContent();

        $data = json_decode($content, true);

        if ($data == null || !isset($data['ch']) || !isset($data['tick'])) {
            return $this->apiResult(1, 'empty data.', $content);
        }
// -------------------------------------------------------------------------------
//        $data = $data ?: [];
//        $data_default = ["ch" => 'market.btcusdt.kline.1min', "ts" => time(),
//            "tick" => ["id" => time(), "open" => 0, "close" => 0, "low" => 0,
//                "high" => 0, "amount" => 0, "vol" => 0, "count" => 0]
//        ];
//        $data = array_replace_recursive($data_default, $data);
// -------------------------------------------------------------------------------

        $coin = explode('.', $data['ch'])[1];
        $tick = $data['tick'];

        $datetime = new \DateTime();
        $timestamp = $tick['id'];
        $datetime->setTimestamp($timestamp);

        $data_now = [
            // KLine
            'open' => $tick['open'],
            'close' => $tick['close'],
            'low' => $tick['low'],
            'high' => $tick['high'],
            'amount' => $tick['amount'],
            'vol' => $tick['vol'],
            'count' => $tick['count'],
            'time' => $datetime,
            'time_stamp' => $timestamp,
            // KDJ
            'k_5mins' => 50.0,
            'd_5mins' => 50.0,
            'k_10mins' => 50.0,
            'd_10mins' => 50.0,
            'rsi_5mins' => 50.0,
            'rsi_10mins' => 50.0,
            'rsi_20mins' => 50.0,
            'rsi_30mins' => 50.0,
        ];

        $em = $this->getDoctrine()->getManager();
        // 获取近四小时(60*4分钟)的数据
        $data = $this->getKline($coin, $timestamp, 60);

        if (isset($data[0])) {
            $data_0 = $data[0];
            if ($data_now['time_stamp'] == $data_0['time_stamp']) {
                return $this->apiResult(1, $coin . ' duplicate item.', '');
            }
            // 开多:前一个kline 5min 大于20返回
            if ($data_0['rsi_5mins'] > 20) {
                return $this->apiResult(2, $coin . ' previous rsi more than 20.', '');
            }
        }

        // time 字段由DateTime 转换为时间格式化字符串(Y-m-d H:i:s)
        $data_now['time'] = $datetime->format('Y-m-d H:i:s');
        // 增加当前JSON数据到返回结果的第一个
        array_unshift($data, $data_now);

        // 计算60数据：统计汇总
        $result = $this->analysis($coin, $data);

        // 开多:当前kline 5min 小于20返回
        if (empty($result) || $result['rsi_5mins'] < 20) {
            return $this->apiResult(2, $coin . ' current rsi less than 20.', '');
        }

        $version = '7.5';
        $prefix = AlertModelConfig::FUTURES_OPEN_LONG;
        $data_now['coin'] = $coin;
        $content = $this->AmazingLog($version, $prefix, $data_now);

        if ($key = $this->cacheKey()) {
            $this->cache($key, $content);
        }

        return $this->apiResult(0, $coin, '');
    }

    private function AmazingLog($version, $prefix, $options)
    {
        $huobiAmazingLog = new HuobiAmazingLog();

        $huobiAmazingLog->setVersion($version)
            ->setReportType($prefix)
            ->setCoin($options['coin'])
            ->setTimeStamp($options['time_stamp'])
            ->setCoinTime((new \DateTime())->setTimestamp($options['time_stamp']))
            ->setCoinOpen($options['open'])
            ->setCoinClose($options['close'])
            ->setCoinLow($options['low'])
            ->setCoinHigh($options['high'])
            ->setCoinAmount($options['amount'])
            ->setCoinVol($options['vol'])
            ->setCoinCount($options['count']);

        $em = $this->container->get('doctrine')->getManager();
        $em->persist($huobiAmazingLog);
        $em->flush();
        return $huobiAmazingLog->toApiJson();
    }

    protected function KlineInstance($data_now, $prefix)
    {
        $huobiMarketKline5min = new HuobiMarketKline5min($data_now, $prefix);
        return $huobiMarketKline5min;
    }

    protected function getKline($coin, $timestamp = 0, $duration = 60)
    {
        $em = $this->getDoctrine()->getManager();
        $data = $em->getRepository('AdminBundle:HuobiMarketKline5min')->get60mins($coin, $timestamp, $duration);
        return $data;
    }

    protected function klinePeriod()
    {
        $kline_multiple = [
            "5" => 5,
        ];

        return $kline_multiple;
    }

    protected function KlineCalcInstance($data)
    {
        $huobiCalcKline5min = new HuobiCalcKline5min($data);
        return $huobiCalcKline5min;

    }

    protected function cacheKey()
    {
        return self::CACHE_KLINE_KEY;
    }

    protected function calcKlineMinSize()
    {
        $min_size = parent::calcKlineMinSize() - 1;
        return $min_size;
    }

}
